from common.exchange.power_shell import ExchangeConsole
import os

class Exchange2008PowerShellSnapin(ExchangeConsole):
    header = 'add-pssnapin microsoft.exchange.management.powershell.admin;'   
    
class ExchangeConsoleHandler(object):
    def __init__(self, exchange_console):
        self.exchange_console = exchange_console
        self._run_ps_cmd = exchange_console._run_ps_cmd
        self.common = exchange_console.common
        
class StorageGroup(ExchangeConsoleHandler):

    def __init__(self, name, server_name = None):
        self.name = name
        self.server_name = server_name
        ExchangeConsoleHandler.__init__(self, Exchange2008PowerShellSnapin())
        
    def get_guid(self):
        [exit_code, out, err] = self._run_ps_cmd('get-storagegroup|where {{$_.name -eq \'{0}\'}}|fl guid'.format(self.name), StorageGroupError)
        for line in out:
            if line != '\n':				
                guid = line.split(':')[1].strip()
                self.common.log.debug('guid for {0} storage group: {1}'.format(self.name, guid))				
                return guid
        self.common.log.debug('no guid found')
        return out

    def set_circular_logging(self, action = True):
        cmd = 'Set-StorageGroup -Identity \'{0}\' -CircularLoggingEnabled ${1}'.format(self.name, str(action).lower())
        self.common.log.debug('setting circular loggin: {0}'.format(action))
        self._run_ps_cmd(cmd, StorageGroupError)

    def get_mailbox_database(self, name):
        self.common.log.debug('return mailbox db object for "{0}"'.format(name))
        return MailboxDatabase(self.exchange_console, name, self.name)

    def get_mailbox_databases(self):
        cmd = 'get-mailboxdatabase|where {{$_.storagegroup -like \'*{0}\'}}|fl name'.format(self.name)
        [exit_code, out, err] = self._run_ps_cmd(cmd, StorageGroupError)
        for line in out:
            if 'Name' in line:
                mailbox_db_name = line.split(':')[1].strip()			
                self.common.log.debug('found mailbox db: {0}'.format(mailbox_db_name))
                yield MailboxDatabase(self.exchange_console, mailbox_db_name, self.name)		

class MailboxDatabase(ExchangeConsoleHandler):

    def __init__(self, exchange_console, name, sg_name = None):
        self.name = name
        self.sg_name = sg_name
        if sg_name == None:
            self.full_name = name
        else:
            self.full_name = '{0}\\{1}'.format(sg_name, name)
        ExchangeConsoleHandler.__init__(self, exchange_console)            

    def set_db_overwritten_by_restore(self, action = True):
        cmd = 'Set-MailboxDatabase \'{0}\' -AllowFileRestore ${1}'.format(self.full_name, str(action).lower())
        self.common.log.debug('set overwritten by restore: {0}'.format(action))
        self._run_ps_cmd(cmd, MailboxDatabaseError)

    def is_db_overwritten_by_restore(self):
        cmd = 'get-mailboxdatabase -identity \'{0}\'|fl allowfilerestore'.format(self.full_name)
        self.common.log.debug('check if overwritten by restore set for : {0}'.format(self.full_name))
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxDatabaseError)
        if 'True' in "".join(out):
            return True
        return False

    def get_mailboxes(self):
        cmd = 'get-mailboxstatistics -database \'{0}\'|fl displayname'.format(self.full_name)
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxDatabaseError)		

        for line in out:
            if 'DisplayName' in line:
                mailbox_name = line.split(':')[1].strip()								
                if 'System' not in mailbox_name and 'Search' not in mailbox_name and 'Microsoft' not in mailbox_name:
                    self.common.log.debug('found mailbox: {0}'.format(mailbox_name))
                    yield Mailbox(mailbox_name, self.full_name, self.exchange_console)

    def mount(self):
        cmd = 'Mount-database \'{0}\''.format(self.full_name)
        self.common.log.debug('mounting mailbox db: {0}'.format(self.full_name))
        self._run_ps_cmd(cmd, MailboxDatabaseError)		

    def dismount(self):
        cmd = 'Dismount-database \'{0}\' -confirm:$false'.format(self.full_name)
        self.common.log.debug('dismounting mailbox db: {0}'.format(self.full_name))
        self._run_ps_cmd(cmd, MailboxDatabaseError)	

    def is_mounted(self):
        cmd = 'get-mailboxdatabase -status -identity \'{0}\'|ft mounted'.format(self.full_name)
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxDatabaseError)		

        for line in out:
            if 'True' in line:
                self.common.log.debug('mailbox db "{0}" is mounted'.format(self.full_name))
                return True
        self.common.log.debug('mailbox db "{0}" is not mounted'.format(self.full_name))
        return False

    def clean(self):
        cmd = 'clean-mailboxdatabase -identity \'{0}\''.format(self.full_name)
        self.common.log.debug('cleanup "{0}"'.format(self.full_name))
        self._run_ps_cmd(cmd, MailboxDatabaseError)			

    def remove(self):
        cmd = 'remove-mailboxDatabase -identity \'{0}\''.format(self.full_name)
        self.common.log.debug('removing "{0}"'.format(self.full_name))
        self._run_ps_cmd(cmd, MailboxDatabaseError)		

    def get_guid(self):
        cmd = 'get-mailboxdatabase -identity \'{0}\'|fl guid'.format(self.full_name)
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxDatabaseError)		
        guid = ''
        for line in out:
            if 'Guid' in line:
                guid = line.split(':')[1].strip()
        self.common.log.debug('guid for database {0}: {1}'.format(self.full_name, guid))
        return guid

    def create_mailbox(self, name):
        cmd = 'enable-mailbox {0} -Database \'{1}\''.format(name, self.full_name)
        self.common.log.debug('create mailbox for existing user account: {0} in "{1}"'.format(name, self.full_name))	
        self._run_ps_cmd(cmd, MailboxDatabaseError)		
        return Mailbox(name, self.full_name, self.exchange_console)

    def create_new_mailbox(self, name, password, domain):
        cmd = '$password = convertto-securestring -asplaintext -force -string \'{0}\';new-mailbox -Name \'{1}\' -Database \'{2}\' -Password $password -UserPrincipalname \'{1}@{3}\''.format(password, name, self.full_name, domain)
        self.common.log.debug('create new mailbox: {0} in "{1}"'.format(name, self.full_name))	
        self._run_ps_cmd(cmd, MailboxDatabaseError)		
        return Mailbox(name, self.full_name, self.exchange_console)

class Mailbox(ExchangeConsoleHandler):

    def __init__(self, name, db_path, exchange_console):
        self.name = name
        self.db_path = db_path
        ExchangeConsoleHandler.__init__(self, exchange_console)  
        
    def _get_dn(self):
        cmd = 'get-mailbox -identity \'{0}\'|fl distinguishedname'        
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxError)	
        for line in out:
            if 'DistinguishedName' in line:
                self.dn = line.split(':')[1].strip()        
        self.common.log.debug('distinguished name: "{0}"'.format(self.dn))

    def connect(self):
        cmd = "Connect-Mailbox -Database \'{0}\' -Identity '{1}' -User '{1}'".format(self.db_path, self.name)
        self.common.log.debug('connecting mailbox "{0}"'.format(self.name))
        self._run_ps_cmd(cmd, MailboxError)				

    def is_connected(self):
        cmd = 'get-mailboxstatistics -database \'{0}\'|where {{$_.disconnectdate -ne $null -and $_.displayname -eq \'{1}\'}}|fl displayname'.format(self.db_path,
                                                                                                                                                    self.name)
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxError)						
        if out == []:
            self.common.log.debug('mailbox "{0}" is connected'.format(self.name))
            return True
        self.common.log.debug('mailbox "{0}" is disconnected'.format(self.name))
        return False	

    def check(self, domain_name):
        cmd = 'test-mapiconnectivity {0}@{1}'.format(self.name, domain_name)		
        [exit_code, out, err] = self._run_ps_cmd(cmd, MailboxError)			
        for line in out:
            if 'Success' in line:
                self.common.log.debug('mailbox "{0}" is checked'.format(self.name))
                return
        raise MailboxError('Possible problem in checking mailbox connectivity with user: {0}'.format(self.name))

class StorageGroupError(Exception):
    pass

class MailboxError(Exception):
    pass

class MailboxDatabaseError(Exception):
    pass										